﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CdcSoftware.Pivotal.Applications.Core.Client;
using CdcSoftware.Pivotal.Engine.Client.ClientTasks.Attributes;
using CdcSoftware.Pivotal.Engine.Client.Services.Interfaces;
using System.Data;
using CdcSoftware.Pivotal.Applications.Core.Common;
using System.Windows.Forms;
using CdcSoftware.Pivotal.Engine;

namespace Pcm.Retail.Client.FormTasks.CommandHandlers
{
    public class RE_AuthorizationCommandHandlers : CommandClientTask
    {
        #region Private Variables.
        private System.Windows.Forms.TextBox txtCurrentPassword, txtNewPassword, txtConfirmPassword;
        private System.Windows.Forms.Button btnOk, btnCancel;
        private System.Windows.Forms.Label lblCurrentPassword, lblNewPassword, lblConfirmPassword;

        private Form popupChangePassword = null;
        private Form popupAuthorization = null;
        private bool changePassword = false;
        private DataTable staff = null;

        private bool recordSavedSucessfully = false;
        #endregion

        [ClientTaskCommand]
        public virtual void Authorize_OnClick()
        {
            try
            {
                if (this.PrimaryDataRow["Staff_Code"] == DBNull.Value)
                {
                    PivotalMessageBox.Show("Please enter Authorization Staff Code.", MessageBoxButtons.OK, MessageBoxIcon.Hand);
                    return;
                }
                //NK 27-Jul-2012:Added a check to ensure the mandatory fields are filled in before Authorize is clicked.

                IFormView formView = ClientContext.ClientAPIService.GetActiveContentObject() as IFormView;
                string strMessage = "Please fill in the mandatory fields.";
                if (formView.VerifyRecord(out strMessage) == false || formView.ValidateRequiredFields(out strMessage) == false)
                {
                    PivotalMessageBox.Show(strMessage, MessageBoxButtons.OK);
                    return;
                }

                if (this.DataSet.Tables["RE_Authorization_Order_Id"].AsEnumerable().Count(a => (TypeConvert.ToBoolean(a["Authorized"]) == true &&
                    a["RE_Authorized_By_Id"] != DBNull.Value)) == this.DataSet.Tables["RE_Authorization_Order_Id"].Rows.Count)
                {
                    PivotalMessageBox.Show("All the events are already Authorized.", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }
                else if (this.DataSet.Tables["RE_Authorization_Order_Id"].AsEnumerable().Count(a => (TypeConvert.ToBoolean(a["Authorized"]) == false &&
                    a["RE_Authorized_By_Id"] == DBNull.Value)) == this.DataSet.Tables["RE_Authorization_Order_Id"].Rows.Count)
                {
                    PivotalMessageBox.Show("None of the events are checked for Authorization.", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }
                DataRow[] loggedInStaff = null;
                //Check whether the staff code is valid or not.
                staff = Globals.GetDataTable("RE_Active Staff with Staff Code?", new object[] { this.PrimaryDataRow["Staff_Code"].ToString() },
                    "RE_Staff_Id", "Authorize", "Prompt_To_Reset", "Password_");
                if (staff != null && staff.Rows.Count == 1)
                {
                    //Check if the Staff is Authorized to Authorize or not.
                    if (!TypeConvert.ToBoolean(staff.Rows[0]["Authorize"]))
                    {
                        PivotalMessageBox.Show("Staff does not have permissions to Authorize.", MessageBoxButtons.OK, MessageBoxIcon.Hand);
                        return;
                    }

                    //Check if the staff is logged in or not.
                    DataTable staffLogin = Globals.GetDataTable("RE_All Staff Logins for Today", null, new string[] { "Staff_Id", "Out_Time", "Role" });

                    loggedInStaff = staffLogin.AsEnumerable().Where(a => Id.Create(a["Staff_Id"]) == Id.Create(staff.Rows[0]["RE_Staff_Id"])
                                            && Convert.IsDBNull(a["Out_Time"])).ToArray();

                    if (loggedInStaff.Count() == 1)
                    {
                        //Check if the Staff is logged-in as In-Charge or not. If not he should not be allowed to do authorize.
                        if (TypeConvert.ToString(loggedInStaff[0]["Role"]) == "In Charge")
                        {
                            //Check if for the selected staff, the Prompt_To_Change field is set to true.
                            if (TypeConvert.ToBoolean(staff.Rows[0]["Prompt_To_Reset"]))
                                ShowChangePasswordPopup();
                            else
                                ShowAuthorizationPopup();
                        }
                        else
                            PivotalMessageBox.Show("Staff needs to login as In Charge to Authorize.", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    else if (loggedInStaff.Count() > 1)
                        PivotalMessageBox.Show("Multiple entry exists for the user. \r\nPlease contact Administrator.", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    else
                        PivotalMessageBox.Show("Staff is not logged In. Please log in to Authorize.", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else if (staff != null && staff.Rows.Count > 1)
                {
                    PivotalMessageBox.Show("Multiple Staffs found for the code entered: " + this.PrimaryDataRow["Staff_Code"].ToString()
                        + "\r\nPlease contact Administrator.", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
                else
                {
                    PivotalMessageBox.Show("No Staff found for the code entered: " + this.PrimaryDataRow["Staff_Code"].ToString() + "\r\nPlease enter a valid code.",
                        MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    this.PrimaryDataRow["Staff_Code"] = DBNull.Value;
                }

                if (recordSavedSucessfully)
                    this.FormView.CloseForm(true);
            }
            catch (Exception ex)
            {
                Globals.HandleException(ex, true);
            }
        }

        /// <summary>
        /// Show the authorization Pop-up.
        /// </summary>
        /// <history>
        /// Revision#      Date            Author          Description
        /// 6.0.9.1        2011-11-18      DS              Initial version for Retail.                                                
        /// </history>
        private void ShowChangePasswordPopup()
        {
            changePassword = true;
            popupChangePassword = new Form();

            this.txtCurrentPassword = new System.Windows.Forms.TextBox();
            this.txtNewPassword = new System.Windows.Forms.TextBox();
            this.txtConfirmPassword = new System.Windows.Forms.TextBox();
            this.btnOk = new System.Windows.Forms.Button();
            this.btnCancel = new System.Windows.Forms.Button();
            this.lblCurrentPassword = new System.Windows.Forms.Label();
            this.lblNewPassword = new System.Windows.Forms.Label();
            this.lblConfirmPassword = new System.Windows.Forms.Label();
            popupChangePassword.SuspendLayout();
            // 
            // txtCurrentPassword
            // 
            this.txtCurrentPassword.Location = new System.Drawing.Point(181, 30);
            this.txtCurrentPassword.Name = "txtCurrentPassword";
            this.txtCurrentPassword.Size = new System.Drawing.Size(109, 20);
            this.txtCurrentPassword.TabIndex = 0;
            this.txtCurrentPassword.UseSystemPasswordChar = true;
            // 
            // txtNewPassword
            // 
            this.txtNewPassword.Location = new System.Drawing.Point(181, 71);
            this.txtNewPassword.Name = "txtNewPassword";
            this.txtNewPassword.Size = new System.Drawing.Size(109, 20);
            this.txtNewPassword.TabIndex = 1;
            this.txtNewPassword.UseSystemPasswordChar = true;
            // 
            // txtConfirmPassword
            // 
            this.txtConfirmPassword.Location = new System.Drawing.Point(181, 112);
            this.txtConfirmPassword.Name = "txtNewPassword";
            this.txtConfirmPassword.Size = new System.Drawing.Size(109, 20);
            this.txtConfirmPassword.TabIndex = 2;
            this.txtConfirmPassword.UseSystemPasswordChar = true;
            // 
            // btnOk
            // 
            this.btnOk.Location = new System.Drawing.Point(134, 161);
            this.btnOk.Name = "Ok";
            this.btnOk.Size = new System.Drawing.Size(75, 23);
            this.btnOk.TabIndex = 3;
            this.btnOk.Text = "Ok";
            this.btnOk.BringToFront();
            this.btnOk.UseVisualStyleBackColor = true;
            this.btnOk.Click += new System.EventHandler(this.Ok_Click);
            // 
            // btnCancel
            // 
            this.btnCancel.Location = new System.Drawing.Point(215, 161);
            this.btnCancel.Name = "Cancel";
            this.btnCancel.Size = new System.Drawing.Size(75, 23);
            this.btnCancel.TabIndex = 4;
            this.btnCancel.Text = "Cancel";
            this.btnCancel.UseVisualStyleBackColor = true;
            // 
            // lblCurrentPassword
            // 
            this.lblCurrentPassword.AutoSize = true;
            this.lblCurrentPassword.Location = new System.Drawing.Point(43, 33);
            this.lblCurrentPassword.Name = "lblCurrentPassword";
            this.lblCurrentPassword.Size = new System.Drawing.Size(138, 15);
            this.lblCurrentPassword.TabIndex = 5;
            this.lblCurrentPassword.Text = "Current Password:";
            // 
            // lblNewPassword
            // 
            this.lblNewPassword.AutoSize = true;
            this.lblNewPassword.Location = new System.Drawing.Point(43, 74);
            this.lblNewPassword.Name = "lblNewPassword";
            this.lblNewPassword.Size = new System.Drawing.Size(138, 15);
            this.lblNewPassword.TabIndex = 5;
            this.lblNewPassword.Text = "New Password:";
            // 
            // lblConfirmPassword
            // 
            this.lblConfirmPassword.AutoSize = true;
            this.lblConfirmPassword.Location = new System.Drawing.Point(43, 115);
            this.lblConfirmPassword.Name = "lblConfirmPassword";
            this.lblConfirmPassword.Size = new System.Drawing.Size(138, 15);
            this.lblConfirmPassword.TabIndex = 6;
            this.lblConfirmPassword.Text = "Confirm Password:";
            // 
            // Form1
            // 
            popupChangePassword.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            popupChangePassword.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            popupChangePassword.AcceptButton = this.btnOk;
            popupChangePassword.CancelButton = this.btnCancel;
            popupChangePassword.ClientSize = new System.Drawing.Size(348, 224);
            popupChangePassword.StartPosition = FormStartPosition.CenterScreen;
            popupChangePassword.Controls.Add(this.lblCurrentPassword);
            popupChangePassword.Controls.Add(this.lblNewPassword);
            popupChangePassword.Controls.Add(this.lblConfirmPassword);
            popupChangePassword.Controls.Add(this.btnOk);
            popupChangePassword.Controls.Add(this.btnCancel);
            popupChangePassword.Controls.Add(this.txtCurrentPassword);
            popupChangePassword.Controls.Add(this.txtNewPassword);
            popupChangePassword.Controls.Add(this.txtConfirmPassword);
            popupChangePassword.Name = "popupChangePassword";
            popupChangePassword.Text = "Change Password";
            popupChangePassword.ResumeLayout(false);
            popupChangePassword.PerformLayout();
            popupChangePassword.ShowDialog();
        }

        /// <summary>
        /// Show the authorization Pop-up.
        /// </summary>
        /// <history>
        /// Revision#      Date            Author          Description
        /// 6.0.9.1        2011-11-18      DS              Initial version for Retail.                                                
        /// </history>
        private void ShowAuthorizationPopup()
        {
            changePassword = false;
            popupAuthorization = new Form();

            this.txtCurrentPassword = new System.Windows.Forms.TextBox();
            this.btnOk = new System.Windows.Forms.Button();
            this.btnCancel = new System.Windows.Forms.Button();
            this.lblCurrentPassword = new System.Windows.Forms.Label();
            popupAuthorization.SuspendLayout();
            // 
            // txtCurrentPassword
            // 
            this.txtCurrentPassword.Location = new System.Drawing.Point(181, 30);
            this.txtCurrentPassword.Name = "txtCurrentPassword";
            this.txtCurrentPassword.Size = new System.Drawing.Size(109, 20);
            this.txtCurrentPassword.TabIndex = 1;
            this.txtCurrentPassword.UseSystemPasswordChar = true;
            // 
            // btnOk
            // 
            this.btnOk.Location = new System.Drawing.Point(134, 80);
            this.btnOk.Name = "Ok";
            this.btnOk.Size = new System.Drawing.Size(75, 23);
            this.btnOk.TabIndex = 2;
            this.btnOk.Text = "Ok";
            this.btnOk.UseVisualStyleBackColor = true;
            this.btnOk.Click += new System.EventHandler(this.Ok_Click);
            // 
            // btnCancel
            // 
            this.btnCancel.Location = new System.Drawing.Point(215, 80);
            this.btnCancel.Name = "Cancel";
            this.btnCancel.Size = new System.Drawing.Size(75, 23);
            this.btnCancel.TabIndex = 3;
            this.btnCancel.Text = "Cancel";
            this.btnCancel.UseVisualStyleBackColor = true;
            // 
            // lblCurrentPassword
            // 
            this.lblCurrentPassword.AutoSize = true;
            this.lblCurrentPassword.Location = new System.Drawing.Point(43, 33);
            this.lblCurrentPassword.Name = "lblCurrentPassword";
            this.lblCurrentPassword.Size = new System.Drawing.Size(138, 15);
            this.lblCurrentPassword.TabIndex = 5;
            this.lblCurrentPassword.Text = "Password:";
            // 
            // Form1
            // 
            popupAuthorization.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            popupAuthorization.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            popupAuthorization.AcceptButton = this.btnOk;
            popupAuthorization.CancelButton = this.btnCancel;
            popupAuthorization.ClientSize = new System.Drawing.Size(348, 133);
            popupAuthorization.StartPosition = FormStartPosition.CenterScreen;
            popupAuthorization.Controls.Add(this.lblCurrentPassword);
            popupAuthorization.Controls.Add(this.btnOk);
            popupAuthorization.Controls.Add(this.btnCancel);
            popupAuthorization.Controls.Add(this.txtCurrentPassword);
            popupAuthorization.Name = "popupAuthorization";
            popupAuthorization.Text = "Enter Password";
            popupAuthorization.ResumeLayout(false);
            popupAuthorization.PerformLayout();
            popupAuthorization.ShowDialog();
        }

        /// <summary>
        /// Event handler for the OK click of the popup pwd challenge.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <history>
        /// Revision#      Date            Author          Description
        /// 6.0.9.1        2011-08-08      DS              Initial version for Retail.                                                
        /// </history>
        private void Ok_Click(object sender, EventArgs e)
        {
            try
            {
                if (changePassword)
                {
                    //Verify the current password is correct and the new password matches the confirm password fields.
                    //Update the new password in the staff table and clear the Prompt_To_Change field and Clock-In the staff.

                    //User selects OK but value not provided.
                    if (txtCurrentPassword.Text.Trim() == string.Empty || txtNewPassword.Text.Trim() == string.Empty || txtConfirmPassword.Text.Trim() == string.Empty)
                    {
                        this.txtCurrentPassword.Text = string.Empty;
                        this.txtNewPassword.Text = string.Empty;
                        this.txtConfirmPassword.Text = string.Empty;
                        this.txtCurrentPassword.Focus();
                        return;
                    }

                    //Match the old password with the DB value. If matched go ahead, esle prompt the user.
                    if (String.Equals(Globals.Decrypt(staff.Rows[0]["Password_"].ToString()), txtCurrentPassword.Text))
                    {
                        //If new password and the confirm password does not match prompt the user with error.
                        if (!String.Equals(txtNewPassword.Text, txtConfirmPassword.Text))
                        {
                            PivotalMessageBox.Show("Password confirmation failed. Please enter again.", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            this.txtNewPassword.Text = string.Empty;
                            this.txtConfirmPassword.Text = string.Empty;
                            this.txtNewPassword.Focus();
                            return;
                        }

                        //Now change the password for the Staff and set the field Prompt_To_Reset to false.
                        this.SystemClient.ExecuteServerTask("RE_Store", "SetStaffPassword", new Type[] { typeof(Id), typeof(string) },
                            new object[] { Id.Create(staff.Rows[0]["RE_Staff_Id"]), Globals.Encrypt(this.txtNewPassword.Text) });

                        //After successful validation and password change, close the pop-up.
                        popupChangePassword.Close();

                        AuthorizeTransactions();
                    }
                    else
                    {
                        PivotalMessageBox.Show("Current Password verification failed. Please enter again.", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        this.txtCurrentPassword.Text = string.Empty;
                        this.txtNewPassword.Text = string.Empty;
                        this.txtConfirmPassword.Text = string.Empty;
                        this.txtCurrentPassword.Focus();
                        return;
                    }
                }
                else
                {
                    //Verify the current password is correct and clock in the staff.
                    //User selects OK but value not provided.
                    if (txtCurrentPassword.Text.Trim() == string.Empty)
                    {
                        this.txtCurrentPassword.Text = string.Empty;
                        this.txtCurrentPassword.Focus();
                        return;
                    }

                    //Match the password with the DB value. If matched go ahead, esle prompt the user.
                    if (String.Equals(Globals.Decrypt(staff.Rows[0]["Password_"].ToString()), txtCurrentPassword.Text))
                    {
                        //After successful validation and password change, close the pop-up.
                        popupAuthorization.Close();
                    }
                    else
                    {
                        PivotalMessageBox.Show("Password verification failed. Please enter again.", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        this.txtCurrentPassword.Text = string.Empty;
                        this.txtCurrentPassword.Focus();
                        return;
                    }

                    AuthorizeTransactions();
                }
            }
            catch (Exception ex)
            {
                Globals.HandleException(ex, true);
            }
        }

        /// <summary>
        /// Authorize the transactions.
        /// </summary>
        private void AuthorizeTransactions()
        {
            foreach (DataRow dr in this.DataSet.Tables["RE_Authorization_Order_Id"].Rows)
            {
                if (TypeConvert.ToBoolean(dr["Authorized"]) && (dr["RE_Authorized_By_Id"] == DBNull.Value))
                {
                    //1st time Authorization.
                    dr["RE_Authorized_By_Id"] = staff.Rows[0]["RE_Staff_Id"];
                    //DS:08102012 - SFA_Order table field "RE_Authorized_By_Id" populated with the last authorized by.
                    //Pls note this is going to be set only when there was some transactions left for authorization and everytime the value gets overwritten.
                    this.PrimaryDataRow["RE_Authorized_By_Id"] = staff.Rows[0]["RE_Staff_Id"];
                }
                else if (!TypeConvert.ToBoolean(dr["Authorized"]) && (dr["RE_Authorized_By_Id"] != DBNull.Value))
                {
                    //Clear-Authorization.
                    dr["RE_Authorized_By_Id"] = DBNull.Value;
                }
            }

            if (this.SaveRecord())
                recordSavedSucessfully = true;
        }
    }
}
